package com.indignado.logicbricks.systems.actuators; import com.badlogic.ashley.core.Engine; import com.badlogic.ashley.core.Entity; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.physics.box2d.Body; import com.badlogic.gdx.utils.reflect.ClassReflection; import com.badlogic.gdx.utils.reflect.Constructor; import com.badlogic.gdx.utils.reflect.ReflectionException; import com.indignado.logicbricks.components.RigidBodiesComponents; import com.indignado.logicbricks.components.StateComponent; import com.indignado.logicbricks.components.actuators.InstanceEntityActuatorComponent; import com.indignado.logicbricks.config.Settings; import com.indignado.logicbricks.core.EntityFactory; import com.indignado.logicbricks.core.actuators.InstanceEntityActuator; import com.indignado.logicbricks.core.actuators.MotionActuator; import com.indignado.logicbricks.core.actuators.StateActuator; import com.indignado.logicbricks.core.controllers.ConditionalController; import com.indignado.logicbricks.core.sensors.AlwaysSensor; import com.indignado.logicbricks.core.sensors.DelaySensor; import com.indignado.logicbricks.utils.Log; import com.indignado.logicbricks.utils.builders.LBBuilders; import com.indignado.logicbricks.utils.builders.actuators.MotionActuatorBuilder; import com.indignado.logicbricks.utils.builders.actuators.StateActuatorBuilder; import com.indignado.logicbricks.utils.builders.controllers.ConditionalControllerBuilder; import com.indignado.logicbricks.utils.builders.sensors.AlwaysSensorBuilder; import com.indignado.logicbricks.utils.builders.sensors.DelaySensorBuilder; /** * @author Rubentxu */ public class InstanceEntityActuatorSystem extends ActuatorSystem<InstanceEntityActuator, InstanceEntityActuatorComponent> { private LBBuilders builders; private AssetManager assetManager; public InstanceEntityActuatorSystem() { super(InstanceEntityActuatorComponent.class); } @Override public void addedToEngine(Engine engine) { super.addedToEngine(engine); builders = context.get(LBBuilders.class); assetManager = context.get(AssetManager.class); } private Constructor findConstructor(Class type) { try { return ClassReflection.getConstructor(type, (Class[]) null); } catch (Exception ex1) { try { Constructor constructor = ClassReflection.getDeclaredConstructor(type, LBBuilders.class, AssetManager.class); constructor.setAccessible(true); return constructor; } catch (ReflectionException ex2) { Log.debug(tag, "Error instance entitySystem %s", ex2.getMessage()); return null; } } } private <T extends EntityFactory> Entity createEntity(Class<T> classFactory) { Constructor constructor = findConstructor(classFactory); T factory; try { factory = (T) constructor.newInstance(builders, assetManager); } catch (Exception ex) { Log.debug(tag, "Error instance entityFactory %s", classFactory.getSimpleName()); return null; } return factory.createEntity(); } @Override public void processActuator(InstanceEntityActuator actuator, float deltaTime) { if (actuator.type == InstanceEntityActuator.Type.AddEntity) { Entity entity = createEntity(actuator.entityFactory); Body body = actuator.owner.getComponent(RigidBodiesComponents.class).rigidBodies.first(); Vector2 position = body.getPosition().cpy(); if (actuator.localPosition != null) position.add(actuator.localPosition); positioningEntity(entity, position.x, position.y, actuator.angle); Log.debug(tag, "Create with position %s", position); if (actuator.initialVelocity != null) { addMotionComponents(entity, actuator); } if (actuator.duration != 0) addDurationComponents(entity, actuator); engine.addEntity(entity); } } public void positioningEntity(Entity entity, float posX, float posY, float angle) { if (Settings.DEBUG_ENTITY != null) tag = Log.tagEntity(this.getClass().getSimpleName(), entity); RigidBodiesComponents rbc = entity.getComponent(RigidBodiesComponents.class); for (Body rigidBody : rbc.rigidBodies) { Vector2 originPosition = new Vector2(posX, posY); originPosition.add(rigidBody.getPosition()); rigidBody.setTransform(originPosition, (rigidBody.getAngle() + angle) * MathUtils.degreesToRadians); Log.debug(tag, "Entity initial position %s", originPosition.toString()); } } private void addDurationComponents(Entity entity, InstanceEntityActuator actuator) { DelaySensor delaySensor = builders.getBrickBuilder(DelaySensorBuilder.class) .setDelay(actuator.duration) .setName("SensorDestroyEntity") .getBrick(); StateActuator stateActuator = builders.getBrickBuilder(StateActuatorBuilder.class) .setChangeState(StateComponent.eraseID) .setName("ChangeStateRemove") .getBrick(); ConditionalController controller = builders.getBrickBuilder(ConditionalControllerBuilder.class) .setOp(ConditionalController.Op.OP_AND) .setName("DurationController") .getBrick(); builders.getEntityBuilder() .initialize(entity) .addController(controller, entity.getComponent(StateComponent.class).getStates()) .connectToSensor(delaySensor) .connectToActuator(stateActuator) .getEntity(); } private void addMotionComponents(Entity entity, InstanceEntityActuator actuator) { AlwaysSensor alwaysSensor = builders.getBrickBuilder(AlwaysSensorBuilder.class) .setName("SensorMotionActuator") .getBrick(); ConditionalController controller = builders.getBrickBuilder(ConditionalControllerBuilder.class) .setOp(ConditionalController.Op.OP_AND) .setName("ControllerMotionActuator") .getBrick(); MotionActuator motionActuator = builders.getBrickBuilder(MotionActuatorBuilder.class) .setVelocity(actuator.initialVelocity) .setName("MotionActuatorInstance") .getBrick(); Log.debug(tag, "Initial Velocity %s Angle %f", actuator.initialVelocity.toString(), actuator.angle); builders.getEntityBuilder() .initialize(entity) .addController(controller, entity.getComponent(StateComponent.class).getStates()) .connectToSensor(alwaysSensor) .connectToActuator(motionActuator) .getEntity(); } }